﻿namespace TelecoSystems.Web.Services.Contracts {
    using System;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using System.Web.Security;
    using TelecoSystems.Web.Models;
    using TelecoSystems.Web.Models.PresentationModel;

    /// <summary>
    /// DomainService exposing domain logic for Contracts management
    /// </summary>
    [RequiresAuthentication]
    [EnableClientAccess()]
    public class ContractsDomainService : LinqToEntitiesDomainService<TelecoSystemsContainer> {
        public IQueryable<ContractPM> GetContracts() {
            var q = from c in ObjectContext.Contracts
                   join cu in ObjectContext.Customers on c.CustomerID equals cu.Id
                   join v in ObjectContext.Variants on c.EditionID equals v.Id
                   select new ContractPM() {
                       Id = c.Id,
                       Created = c.DateCreated,
                       LastModified = c.DateLastModified,
                       CustomerId = cu.Id,
                       CustomerAddress = cu.AddressStreet + " " + cu.AddressCity + " " + cu.AddressCountry + " " + cu.AddressPostalCode,
                       CustomerEmail = cu.Email,
                       CustomerName = cu.Name,
                       DealerId = c.DealerID,
                       //DealerName = scalar method returning dealer name from dealer id
                       Price = v.Price,
                       ProductId = v.ProductID,
                       ProductName = v.Product.Name,
                       ProductDescription = v.Product.Description,
                       VariantId = v.Id,
                       VariantName = v.Name,
                       VarinatDescription = v.Description
                   };
            
            foreach(ContractPM cpm in q) {
                cpm.DealerName = getUserName(cpm.DealerId);
            }
            
            return q; 
        }

        /// <summary>
        /// Method for retrieval of user friendly name
        /// </summary>
        /// <param name="userId">user's Id</param>
        /// <returns>friendly name</returns>
        private string getUserName(Guid userId) {
            AuthenticationService authService = new AuthenticationService();
            try {
                //Retrieve user with specified Id
                User user = authService.GetUserByGuid(userId);
                return user.FriendlyName;
                
                //MembershipUser user = Membership.GetUser(userId);
                //return (user.Comment != "") ? user.Comment : user.Email;
            } catch {
                return "N/A";
            }
        }
        
        public void InsertContract(ContractPM contractPM) {
            Contract contract = new Contract();

            //Map PresentationModel -> Entity
            contract.CustomerID = contractPM.CustomerId;
            contract.DateLastModified = contract.DateCreated = DateTime.Now;
            contract.DealerID = (Guid)Membership.GetUser().ProviderUserKey;
            contract.EditionID = contractPM.VariantId;

            //Resolve id
            if (this.ObjectContext.Contracts.Count() > 0) {
                contract.Id = this.ObjectContext.Contracts.Max(c => c.Id) + 1;
            } else {
                contract.Id = 1;
            }

            if ((contract.EntityState != EntityState.Detached)) {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(contract, EntityState.Added);
            } else {
                this.ObjectContext.Contracts.AddObject(contract);
            }
        }

        [Update]
        public void UpdateContract(ContractPM currentContractPM) {
            Contract currentContract = ObjectContext.Contracts.Where(c => c.Id == currentContractPM.Id).FirstOrDefault();
            currentContract.EditionID = currentContractPM.VariantId;
            currentContract.DateLastModified = DateTime.Now;         

            ObjectContext.SaveChanges();
        }

        public void DeleteContract(ContractPM contractPM) {
            Contract contract = ObjectContext.Contracts.Where(c => c.Id == contractPM.Id).FirstOrDefault();

            if ((contract.EntityState == EntityState.Detached)) {
                this.ObjectContext.Contracts.Attach(contract);
            }
            this.ObjectContext.Contracts.DeleteObject(contract);
        }
    }
}